#include "Scoreboard.h"
#include "UserInterface.h"
#include "Assert.h"

const unsigned int Scoreboard::SIZE;

void Scoreboard::addScore(const string & playerName, const int & moves) throw (invalid_argument) {
	if (moves <= 0) {
		throw (invalid_argument("Player's moves must be > 0."));
	}
	if (!UserInterface::validName(playerName)) {
		throw (invalid_argument("Invalid player name."));
	}
	if (!this->isTopScore(moves)) {
		return;
	}
	ASSERT(this->scores.size() <= SIZE);
	if (this->scores.size() == SIZE) {
		this->scores.pop_back();
	}
	this->scores.push_back(Score(playerName, moves));
	this->scores.sort(Score::compare);
}

bool Scoreboard::isTopScore(const int & moves) throw (invalid_argument) {
	if (moves <= 0) {
		throw (invalid_argument("Player's moves must be > 0."));
	}
	if (this->scores.size() < SIZE) {
		return true;
	}
	else {
		if (this->scores.back().moves > moves) {
			return true;
		}
	}
	return false;
}

ostream & operator <<(ostream & outputStream, const Scoreboard & scoreboard){
	if (scoreboard.scores.empty()) {
		outputStream << "The scoreboard is empty." << endl;
		return outputStream;
	}
	outputStream << "Scoreboard:" << endl;
	int position = 1;
	for (list<Scoreboard::Score>::const_iterator score = scoreboard.scores.begin();
		score != scoreboard.scores.end(); score++) {
		outputStream << position << ". " << score->playerName << " --> "
			<< score->moves << " moves" << endl;
		position++;
	}
	return outputStream;
}

//returns true if the first argument must go before the second argument
//when sorting and false otherwise.
bool Scoreboard::Score::compare(const Score & first, const Score & second) {
	if (first.moves < second.moves) {
		return true;
	}
	else {
		return false;
	}
}
